package com.xsd.parser.parse.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.xsd.parser.XsdParserMain;
import com.xsd.parser.model.ElementListModel;
import com.xsd.parser.module.AnnotationModel;
import com.xsd.parser.module.ElementModel;
import com.xsd.parser.module.ImportModel;
import com.xsd.parser.module.SchemaModel;
import com.xsd.parser.parse.ExcelParseToCollection;
import com.xsd.parser.tools.ReadXslxFile;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author cetc
 */
public class ExcelParseToCollectionImpl implements ExcelParseToCollection {

    private File excelFile;

    public ExcelParseToCollectionImpl(String excelPath) {
        this.excelFile = XsdParserMain.checkFile(excelPath);
    }

    @Override
    public List<SchemaModel> schemaParse() throws Exception{

        //读取excel文件
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setKeyIndex(0);
        params.setStartSheetIndex(0);
        FileInputStream ip = null;
        try {
            ip = new FileInputStream(excelFile);
            //解析excel
            List<SchemaModel> result = ExcelImportUtil.importExcel(ip, SchemaModel.class, params);
            // System.out.println("文档schema:\n"+result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ip.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public List<ImportModel> importParse() {
        //读取excel文件
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setKeyIndex(0);
        params.setStartSheetIndex(1);
        FileInputStream ip = null;
        try {
            ip = new FileInputStream(excelFile);
            //解析excel
            List<ImportModel> result = ExcelImportUtil.importExcel(ip, ImportModel.class, params);
            // System.out.println("文档Import:\n"+result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ip.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public List<AnnotationModel> annotationParse() {
        //读取excel文件
        ImportParams params = new ImportParams();
        params.setHeadRows(1);
        params.setKeyIndex(0);
        //sheet序号
        params.setStartSheetIndex(2);
        FileInputStream ip = null;
        try {
            ip = new FileInputStream(excelFile);
            //解析excel
            List<AnnotationModel> result = ExcelImportUtil.importExcel(ip, AnnotationModel.class, params);
            // System.out.println("文档Annotation:\n"+result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ip.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public List<ElementListModel> elementParse() throws Exception {

        //获取excel文件的sheet个数
        int sheetNum = 0;
        HSSFWorkbook hs = null;
        try {
            FileInputStream finput = new FileInputStream(excelFile);
            POIFSFileSystem fs = new POIFSFileSystem( finput );
            hs = new HSSFWorkbook(fs);
            sheetNum = hs.getNumberOfSheets();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Pattern pattern= Pattern.compile("[\u4e00-\u9fa5]");

        List<ElementListModel> mapList = new ArrayList<>();
        int seq = 0;

        for (int sheetIndex=3; sheetIndex<sheetNum; sheetIndex++) {
            ImportParams params = new ImportParams();
            params.setHeadRows(1);
            params.setKeyIndex(3);
            //读取sheet的起始位置
            params.setStartSheetIndex(sheetIndex);
            FileInputStream ip = new FileInputStream(excelFile);
            //解析excel
            List<ElementModel> result = ExcelImportUtil.importExcel(ip, ElementModel.class, params);

            for (int i=0; i<result.size(); i++) {
                //complexType
                if(result.get(i).getElementType().equalsIgnoreCase("xs:complexType")
                        || result.get(i).getElementType().equalsIgnoreCase("complexType")
                        || result.get(i).getElementType().equalsIgnoreCase("xs:simpleType")
                        || result.get(i).getElementType().equalsIgnoreCase("simpleType")
                        || result.get(i).getElementType().equalsIgnoreCase("自由组件") ){

                    //外层组件对象
                    ElementListModel complexType = new ElementListModel();
                    ElementModel emt = result.get(i);
                    complexType.setElementLirTag(emt.getElementLirTag());
                    complexType.setVersion(emt.getVersion());
                    String elementType = emt.getElementType();
                    if(elementType.startsWith("xs:")){
                        elementType = elementType.toLowerCase();
                    }else {
                        elementType = "xs:"+elementType.toLowerCase();
                    }
                    complexType.setElementType(elementType);

                    String seqStr = ReadXslxFile.generateModuleIde(elementType,seq+=1);
                    if(seqStr.equals("")){seq -= 1;}
                    complexType.setDataModuleTag(seqStr);
                    complexType.setDataTypeEN(emt.getDataTypeEN());
                    complexType.setDataElementEN(emt.getDataElementEN());
                    complexType.setDataModuleCN(emt.getDataModuleCN());
                    complexType.setDataBaseTypeEN(emt.getDataBaseTypeEN());
                    complexType.setDataModuleDefEN(emt.getDataModuleDefEN());
                    complexType.setDataModuleDefCN(emt.getDataModuleDefCN());
                    complexType.setAllRefStandard(emt.getAllRefStandard());
                    // System.out.println("上层数据：\t"+complexType);

                    //子项数据
                    List<ElementListModel>  elementList = new ArrayList<ElementListModel>();
                    for (int j= i+1; j<result.size(); j++) {

                        //复合对象等进行子项数据中断读取操作
                        if(result.get(j).getElementType().equalsIgnoreCase("xs:complexType")
                                || result.get(j).getElementType().equalsIgnoreCase("complexType")
                                || result.get(j).getElementType().equalsIgnoreCase("xs:simpleType")
                                || result.get(j).getElementType().equalsIgnoreCase("simpleType")
                                || result.get(j).getElementType().equalsIgnoreCase("自由组件")){
                            i = j-1;
                            complexType.setElementList(elementList);
                            break;
                        }
                        //子项数据列表
                        ElementListModel elementModel = new ElementListModel();
                        ElementModel em = result.get(j);

                        //校验其他字段是否全为空
                        if(em.checkOtherNull()){continue;}

                        elementModel.setElementLirTag(em.getElementLirTag());
                        elementModel.setVersion(em.getVersion());
                        String elementTypeSub = em.getElementType();
                        if(elementTypeSub.startsWith("xs:")){
                            elementTypeSub = elementTypeSub.toLowerCase();
                        }else {
                            elementTypeSub = "xs:"+elementTypeSub.toLowerCase();
                        }
                        elementModel.setElementType(elementTypeSub);
                        seqStr = ReadXslxFile.generateModuleIde(elementTypeSub, seq += 1);
                        if(seqStr.equals("")){seq -= 1;}
                        elementModel.setDataModuleTag(seqStr);
                        elementModel.setDataTypeEN(em.getDataTypeEN());
                        elementModel.setDataElementEN(em.getDataElementEN());
                        elementModel.setDataModuleCN(em.getDataModuleCN());
                        String type = em.getDataBaseTypeEN();
                        if(!pattern.matcher(em.getDataElementEN()).find() && type.isEmpty()){
                            throw new Exception("表格："+hs.getSheetName(sheetIndex)+"第"+j+"行"+
                                    "\n数据元素英文名称："+em.getDataElementEN()+
                                    "\n说明：如果声明抽象元素，“数据类型基类/数据元素约束类型英文名称”列必须使用“<抽象元素，没有类型>”进行标记");
                        }
                        if(type.equalsIgnoreCase("abstract")
                                || "<抽象元素，没有类型>".equalsIgnoreCase(type)
                                || type.contains("抽象")
                                || em.getDataElementEN().trim().toLowerCase().endsWith("abstract")) {
                            type = "abstract";
                        }
                        elementModel.setDataBaseTypeEN(type);
                        elementModel.setDataModuleDefEN(em.getDataModuleDefEN());
                        elementModel.setDataModuleDefCN(em.getDataModuleDefCN());
                        elementModel.setAllRefStandard(em.getAllRefStandard());
                        /**
                         * 判断是否为抽象元素的替换元素
                         */
                        boolean  cnFlag= pattern.matcher(em.getDataElementEN()).find();
                        if(!cnFlag && !"".equals(elementModel.getDataElementEN())) {
                            elementList.add(elementModel);
                        }

                        if(type.equalsIgnoreCase("abstract")){
                            //下一个为替换元素
                            if((j+1)<result.size() && !result.get(j+1).getDataElementEN().trim().isEmpty()){
                                if(result.get(j+1).getDataElementEN().trim().startsWith("替换元素")) {
                                    for (int k = j + 2; k < result.size(); k++) {
                                        //非“/”开头抽象元素完成
                                        if (!result.get(k).getDataElementEN().startsWith("/")) {
                                            j = k - 1;
                                            break;
                                        } else {
                                            //抽象数据列表
                                            ElementListModel abstractModel = new ElementListModel();
                                            ElementModel ema = result.get(k);
                                            abstractModel.setElementLirTag(ema.getElementLirTag());

                                            abstractModel.setVersion(ema.getVersion());

                                            String elementTypeAbs = ema.getElementType();
                                            if (elementTypeAbs.startsWith("xs:")) {
                                                elementTypeAbs = elementTypeAbs.toLowerCase();
                                            } else {
                                                elementTypeAbs = "xs:" + elementTypeAbs.toLowerCase();
                                            }
                                            abstractModel.setElementType(elementTypeAbs);
                                            seqStr = ReadXslxFile.generateModuleIde(elementTypeAbs, seq += 1);
                                            if (seqStr.equals("")) {
                                                seq -= 1;
                                            }
                                            abstractModel.setDataModuleTag(seqStr);
                                            abstractModel.setDataTypeEN(ema.getDataTypeEN());
                                            abstractModel.setDataElementEN(ema.getDataElementEN().replaceFirst("/", ""));
                                            abstractModel.setDataModuleCN(ema.getDataModuleCN());
                                            abstractModel.setDataBaseTypeEN(ema.getDataBaseTypeEN());
                                            abstractModel.setDataModuleDefEN(ema.getDataModuleDefEN());
                                            abstractModel.setDataModuleDefCN(ema.getDataModuleDefCN());
                                            abstractModel.setAllRefStandard(ema.getAllRefStandard());
                                            abstractModel.setSubstitutionGroup(em.getDataElementEN());
                                            cnFlag = pattern.matcher(ema.getDataElementEN()).find();
                                            if (!cnFlag && !"".equals(abstractModel.getDataElementEN())) {
                                                elementList.add(abstractModel);
                                            }
                                        }
                                    }
                                }else{
                                    throw new Exception("表格："+hs.getSheetName(sheetIndex)+
                                            "\n数据元素英文名称："+em.getDataElementEN()+
                                            "\n说明：声明替换元素，必须使用“替换元素：”进行标记");
                                }
                            }
                        }
                    }
                    complexType.setElementList(elementList);
                    mapList.add(complexType);
                }
            }
        }
        return mapList;
    }
}
